/*
||
|| @ Archivo MuxShield.cpp
|| @ Libreria para trabajar con Mux Shield de mayhewlabs y Arduino.
|| @ Desarrollado por Pablo Nahuel Ontivero Castro
|| @ Version 0.1
|| @ contacto pablo@lanzate.com
||
|| @ Para mas informacion sobre Mux Shield, visite:
|| @ http://mayhewlabs.com/products/arduino-mux-shield
||
|| @ Descripcion
|| | Con esta libreria basta con definir de una manera mas comodo
|| | como trabajar con la I/O en la que colocamos nuestra señal.
|| #
||
|| @ Licencia
|| | Esta libreria es software libre, puedes distribuirlar y/o
|| | modificarla bajo los terminos de la Licencia Pública General 
|| | Reducida de GNU publicada por la Free Software Foundation,
|| | version 3 de la licencia.
|| |
|| | Esta libreria es distribuida con la esperanza de que sea util
|| | para todo aquel que la necesite pero SIN NINGUNA GARANTIA, para
|| | mas informacion lea la Licencia Pública General Reducida de GNU
|| | incluida en la carpeta de la libreria con el nombre LGPL3.txt
|| |
|| | Debe recebir una cipia de la Licencia Publica General Reducida de GNU
|| | con esta libreria, en caso de no recibirla, escriba a Free Software
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
|| #
||
*/

#include <MuxShield.h>

// Constructor //
Mux::Mux() {

}

// Configura las I/O de Arduino para trabajar como salida
void Mux::control(){
	pinMode(CONTROL0, OUTPUT);
	pinMode(CONTROL1, OUTPUT);
	pinMode(CONTROL2, OUTPUT);
	pinMode(CONTROL3, OUTPUT);
}

// Funcion principal que se encarga de ejecutar las respectivas funciones segun se declare su forma de trabajo.

void Mux::io(String FunSignal, int LineSignal, int ActivePin, int Activate){
	Activar(convertir(ActivePin));
	Selector(LineSignal, FunSignal);
	if (Activate == 1) {
		Encender(LineSignal);
	} else {
		Apagar(LineSignal);
	}
}

int Mux::lecturaanalogica(int LineSignal, int ActivePin){
	Activar(convertir(ActivePin));
	return (analogRead(LineSignal));
}

// Convierte la entrada del pin seleccionado de hexadecimal a binario para poder configurar las lineas de control

String Mux::convertir(int ActivePin) {
	int zeros = 4 - String(ActivePin,BIN).length();
	String myStr;
	for (int i = 0; i < zeros; i++) {
		myStr = myStr + "0";
	}
	myStr = myStr + String(ActivePin,BIN);
	return myStr;
}

// Convierte la entrada del pin seleccionado de hexadecimal a binario para poder configurar las lineas de control

void Mux::Activar(String ActivePin){
	if (ActivePin[0] == '0') {
		digitalWrite(CONTROL0, OFF); //S3
	} else {
		digitalWrite(CONTROL0, ON); //S3
	}
	if (ActivePin[1] == '0') {
		digitalWrite(CONTROL1, OFF);  //S2
	} else {
		digitalWrite(CONTROL1, ON);  //S2
	}
	if (ActivePin[2] == '0') {
		digitalWrite(CONTROL2, OFF);  //S1
	} else {
		digitalWrite(CONTROL2, ON);  //S1
	}
	if (ActivePin[3] == '0') {
		digitalWrite(CONTROL3, OFF);     //S0 
	} else {
		digitalWrite(CONTROL3, ON);     //S0 
	}
}

// Selecciona el Mux correspondiente

void Mux::Selector(int LineSignal, String FunSignal){
	if (FunSignal == "DO"){
		if (LineSignal == 0) {
			pinMode(MUX0, OUTPUT);
			pinMode(MUX1, INPUT);
			pinMode(MUX2, INPUT);
		}
		if (LineSignal == 1) {
			pinMode(MUX0, INPUT);
			pinMode(MUX1, OUTPUT);
			pinMode(MUX2, INPUT);
		}
		if (LineSignal == 2) {
			pinMode(MUX0, INPUT);
			pinMode(MUX1, INPUT);
			pinMode(MUX2, OUTPUT);
		}
	}
	if (FunSignal == "DI"){
		if (LineSignal == 0) {
			pinMode(MUX0, INPUT);
			pinMode(MUX1, OUTPUT);
			pinMode(MUX2, OUTPUT);
		}
		if (LineSignal == 1) {
			pinMode(MUX0, OUTPUT);
			pinMode(MUX1, INPUT);
			pinMode(MUX2, OUTPUT);
		}
		if (LineSignal == 2) {
			pinMode(MUX0, OUTPUT);
			pinMode(MUX1, OUTPUT);
			pinMode(MUX2, INPUT);
		}
	}
}

// Activa el Mux correspondiente para su I/O

void Mux::Encender(int LineSignal){
	if (LineSignal == 0) {
		digitalWrite(MUX0, ON);
	}
	if (LineSignal == 1) {
		digitalWrite(MUX1, ON);
	}
	if (LineSignal == 2) {
		digitalWrite(MUX2, ON);
	}
}

// Desactiva el Mux correspondiente para su I/O

void Mux::Apagar(int LineSignal){
	if (LineSignal == 0) {
		digitalWrite(MUX0, OFF);
	}
	if (LineSignal == 1) {
		digitalWrite(MUX1, OFF);
	}
	if (LineSignal == 2) {
		digitalWrite(MUX2, OFF);
	}
}

// Devuelve la lectura de una señal digital

byte Mux::lecturadigital(int LineSignal) {
	if (LineSignal == 0) {
		return (digitalRead(MUX0));
	}
	if (LineSignal == 1) {
		return (digitalRead(MUX1));
	}
	if (LineSignal == 2) {
		return (digitalRead(MUX2));
	}
}